home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / prg_gen / euphor14.zip / GET.E < prev    next >
Text File  |  1996-04-05  |  7KB  |  322 lines

  1.         ------------------------------------
  2.         -- Input and Conversion Routines: --
  3.         -- get()                          --
  4.         -- value()                        --
  5.         -- wait_key()                     --
  6.         ------------------------------------
  7.  
  8. constant M_WAIT_KEY = 26
  9.  
  10. constant DIGITS = "0123456789",
  11.      HEX_DIGITS = DIGITS & "ABCDEF",
  12.      START_NUMERIC = DIGITS & "-+.#"
  13.  
  14. global function wait_key()
  15. -- Get the next key pressed by the user.
  16. -- Wait until a key is pressed.
  17.     return machine_func(M_WAIT_KEY, 0)
  18. end function
  19.  
  20.  
  21. -- error status values returned from get() and value():
  22. global constant GET_SUCCESS = 0,
  23.         GET_EOF = -1,
  24.         GET_FAIL = 1
  25.  
  26. constant UNDEFINED_CHAR = -2
  27.  
  28. constant TRUE = 1
  29.  
  30. type natural(integer x)
  31.     return x >= 0
  32. end type
  33.  
  34. type char(integer x)
  35.     return x >= UNDEFINED_CHAR and x <= 255
  36. end type
  37.  
  38. natural input_file  -- file to be read from
  39.  
  40. object input_string -- string to be read from
  41. natural string_next
  42.  
  43. char ungot_char     -- can "unget" one char
  44.  
  45. function get_char()
  46. -- read next logical char in input stream (either string or file)
  47.     char next_char
  48.  
  49.     if ungot_char = UNDEFINED_CHAR then
  50.     if sequence(input_string) then
  51.         if string_next <= length(input_string) then
  52.         next_char = input_string[string_next]
  53.         string_next = string_next + 1
  54.         return next_char
  55.         else
  56.         return GET_EOF
  57.         end if
  58.     else    
  59.         return getc(input_file)
  60.     end if
  61.     else
  62.     next_char = ungot_char
  63.     ungot_char = UNDEFINED_CHAR
  64.     return next_char
  65.     end if
  66. end function
  67.  
  68. procedure unget(char c)
  69. -- "unget" a character - push it back on the input stream
  70.     ungot_char = c
  71. end procedure
  72.  
  73. procedure skip_blanks()
  74. -- skip white space
  75.     char c
  76.  
  77.     while TRUE do
  78.     c = get_char()
  79.     if not find(c, " \t\n") then
  80.         exit
  81.     end if
  82.     end while
  83.     unget(c)
  84. end procedure
  85.  
  86. constant ESCAPE_CHARS = "nt'\"\\r",
  87.      ESCAPED_CHARS = "\n\t'\"\\\r"
  88.  
  89. function escape_char(char c)
  90. -- return escape character
  91.     natural i
  92.  
  93.     i = find(c, ESCAPE_CHARS)
  94.     if i = 0 then
  95.     return GET_FAIL
  96.     else
  97.     return ESCAPED_CHARS[i]
  98.     end if
  99. end function
  100.  
  101. function get_qchar()
  102. -- get a single-quoted character
  103.  
  104.     char c
  105.  
  106.     c = get_char()
  107.     if c = '\\' then
  108.     c = escape_char(get_char())
  109.     if c = GET_FAIL then
  110.         return {GET_FAIL, 0}
  111.     end if
  112.     end if
  113.     if get_char() != '\'' then
  114.     return {GET_FAIL, 0}
  115.     else
  116.     return {GET_SUCCESS, c}
  117.     end if
  118. end function
  119.  
  120.  
  121. function get_string()
  122. -- get a double-quoted character string
  123.     sequence text
  124.     char c
  125.  
  126.     text = ""
  127.     while TRUE do
  128.     c = get_char()
  129.     if c = GET_EOF or c = '\n' then
  130.         return {GET_FAIL, 0}
  131.     end if
  132.     if c = '"' then
  133.         exit
  134.     elsif c = '\\' then
  135.         c = escape_char(get_char())
  136.         if c = GET_FAIL then
  137.         return {GET_FAIL, 0}
  138.         end if
  139.     end if
  140.     text = text & c
  141.     end while
  142.     return {GET_SUCCESS, text}
  143. end function
  144.  
  145. type plus_or_minus(integer x)
  146.     return x = -1 or x = +1
  147. end type
  148.  
  149. function get_number()
  150. -- read a number
  151.     char c
  152.     plus_or_minus sign, e_sign
  153.     natural ndigits
  154.     integer hex_digit
  155.     atom mantissa, dec, e_mag, exponent
  156.  
  157.     sign = +1
  158.     mantissa = 0
  159.     e_sign = +1
  160.     e_mag = 0
  161.     ndigits = 0
  162.  
  163.     c = get_char()
  164.  
  165.     -- process sign
  166.     if c = '-' then
  167.     sign = -1
  168.     elsif c != '+' then
  169.     unget(c)
  170.     end if
  171.  
  172.     -- get mantissa
  173.     c = get_char()
  174.     if c = '#' then
  175.     -- process hex integer and return
  176.     while TRUE do
  177.         c = get_char()
  178.         hex_digit = find(c, HEX_DIGITS)-1
  179.         if hex_digit >= 0 then
  180.         ndigits = ndigits + 1
  181.         mantissa = mantissa * 16 + hex_digit
  182.         else
  183.         unget(c)
  184.         if ndigits > 0 then
  185.             return {GET_SUCCESS, sign * mantissa}
  186.         else
  187.             return {GET_FAIL, 0}
  188.         end if
  189.         end if
  190.     end while       
  191.     end if
  192.     -- decimal integer or floating point
  193.     while c >= '0' and c <= '9' do
  194.     ndigits = ndigits + 1
  195.     mantissa = mantissa * 10 + (c - '0')
  196.     c = get_char()
  197.     end while
  198.     if c = '.' then
  199.     -- get fraction
  200.     c = get_char()
  201.     dec = 10
  202.     while c >= '0' and c <= '9' do
  203.         ndigits = ndigits + 1
  204.         mantissa = mantissa + (c - '0') / dec
  205.         dec = dec * 10
  206.         c = get_char()
  207.     end while
  208.     end if
  209.     if ndigits = 0 then
  210.     return {GET_FAIL, 0}
  211.     end if
  212.     if c = 'e' or c = 'E' then
  213.     -- get exponent sign
  214.     c = get_char()
  215.     if c = '-' then
  216.         e_sign = -1
  217.     elsif c != '+' then
  218.         unget(c)
  219.     end if
  220.     -- get exponent magnitude 
  221.     c = get_char()
  222.     if c >= '0' and c <= '9' then
  223.         e_mag = c - '0'
  224.         c = get_char()
  225.         while c >= '0' and c <= '9' do
  226.         e_mag = e_mag * 10 + c - '0'
  227.         c = get_char()                          
  228.         end while
  229.         unget(c)
  230.     else
  231.         return {GET_FAIL, 0} -- no exponent
  232.     end if
  233.     else
  234.     unget(c)
  235.     end if
  236.     exponent = 1
  237.     if e_sign >= 0 then
  238.     for i = 1 to e_mag do
  239.         exponent = exponent * 10
  240.     end for
  241.     else
  242.     for i = 1 to e_mag do
  243.         exponent = exponent * 0.1
  244.     end for
  245.     end if
  246.     return {GET_SUCCESS, sign * mantissa * exponent}
  247. end function
  248.  
  249. function Get()
  250. -- read a Euphoria data object as a string of characters
  251. -- and return {error_flag, value}
  252.     char c
  253.     sequence s, e
  254.  
  255.     skip_blanks()
  256.     c = get_char()
  257.  
  258.     if find(c, START_NUMERIC) then
  259.     unget(c)
  260.     return get_number()
  261.  
  262.     elsif c = '{' then
  263.     -- process a sequence
  264.     s = {}
  265.     while TRUE do
  266.         skip_blanks()
  267.         c = get_char()
  268.         if c = '}' then
  269.         return {GET_SUCCESS, s}
  270.         else
  271.         unget(c)
  272.         end if
  273.         e = Get()
  274.         if e[1] != GET_SUCCESS then
  275.         return e
  276.         end if
  277.         s = append(s, e[2])
  278.         skip_blanks()
  279.         c = get_char()
  280.         if c = '}' then
  281.         return {GET_SUCCESS, s}
  282.         elsif c != ',' then
  283.         return {GET_FAIL, 0}
  284.         end if
  285.     end while
  286.  
  287.     elsif c = '\"' then
  288.     return get_string()
  289.  
  290.     elsif c = '\'' then
  291.     return get_qchar()
  292.  
  293.     elsif c = -1 then
  294.     return {GET_EOF, 0}
  295.  
  296.     else
  297.     return {GET_FAIL, 0}
  298.  
  299.     end if
  300. end function
  301.  
  302. global function get(integer file)
  303. -- Read the string representation of a Euphoria object 
  304. -- from a file. Convert to the value of the object.
  305. -- Return {error_status, value}.
  306.     input_file = file
  307.     input_string = 0
  308.     ungot_char = UNDEFINED_CHAR
  309.     return Get()
  310. end function
  311.  
  312. global function value(sequence string)
  313. -- Read the representation of a Euphoria object
  314. -- from a sequence of characters. Convert to the value of the object.
  315. -- Return {error_status, value).
  316.     input_string = string
  317.     string_next = 1
  318.     ungot_char = UNDEFINED_CHAR
  319.     return Get()
  320. end function
  321.  
  322.